# deploy_media.py
import paramiko
import os
import subprocess

# 获取当前脚本所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))

# ==================== 配置区域 ====================
# --- 服务器信息 (与 deploy.py 保持一致) ---
SERVER_IP = '47.97.17.103'
SERVER_PORT = 22
USERNAME = 'root'

# --- 认证方式 (二选一) ---
# 方式一：使用密码 (不推荐在生产环境使用)
PASSWORD = 'Zhh1570865'

# --- 文件和路径信息 ---
# 本地 Go media 服务 main.go 所在的目录
LOCAL_BUILD_DIR = os.path.join(current_dir, '..\\..\\services\\media\\cmd')
# 编译后生成的可执行文件名
OUTPUT_FILENAME = 'media_server'
# 组合成本地完整文件路径
LOCAL_FILE_PATH = os.path.join(LOCAL_BUILD_DIR, OUTPUT_FILENAME)
# 上传到服务器的目标目录 (与 deploy.py 保持一致)
REMOTE_DIR = '/home/teck/'
# =================================================

def build_linux_binary():
    """
    构建 media 服务的 Linux 版本二进制文件
    """
    print("0. 正在构建 media 服务 Linux 版本二进制文件...")
    env = os.environ.copy()
    env["GOOS"] = "linux"
    env["GOARCH"] = "amd64"
    env["CGO_ENABLED"] = "0"
    
    # 使用 go build 命令编译，工作目录是 main.go 所在的目录
    result = subprocess.run(
        ["go", "build", "-o", OUTPUT_FILENAME, "."],
        cwd=LOCAL_BUILD_DIR, # 在 main.go 所在的目录执行
        env=env,
        capture_output=True,
        text=True
    )
    if result.returncode != 0:
        print("构建失败：")
        print(result.stdout)
        print(result.stderr)
        raise RuntimeError("Go 构建失败")
    print(f"构建成功！输出文件: {LOCAL_FILE_PATH}")

def main():
    """
    主函数，执行部署流程
    """

    # 先构建 Linux 二进制
    build_linux_binary()  

    ssh_client = None
    try:
        # 从配置中获取可执行文件名 (media_server)
        executable_name = OUTPUT_FILENAME
        remote_file_path = os.path.join(REMOTE_DIR, executable_name).replace('\\', '/')

        # 1. 创建 SSH 客户端
        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        print("1. 正在创建 SSH 客户端...")

        # 2. 连接服务器
        print(f"2. 正在连接到服务器 {SERVER_IP}...")
        ssh_client.connect(SERVER_IP, port=SERVER_PORT, username=USERNAME, password=PASSWORD)
        print(">>> 连接成功！")

        # 3. 停止远程服务器上正在运行的旧程序
        print(f"3. 正在尝试停止旧的 '{executable_name}' 进程...")
        kill_command = f"pkill -f {executable_name}"
        stdin, stdout, stderr = ssh_client.exec_command(kill_command)
        exit_status = stdout.channel.recv_exit_status()
        if exit_status == 0:
            print(">>> 旧进程已停止。")
        else:
            print(">>> 没有找到正在运行的旧进程。")

        # 4. 上传新文件
        print(f"4. 正在上传文件 {LOCAL_FILE_PATH} 到 {remote_file_path}...")
        sftp = ssh_client.open_sftp()
        try:
            sftp.stat(REMOTE_DIR)
        except FileNotFoundError:
            print(f">>> 远程目录 {REMOTE_DIR} 不存在，正在创建...")
            sftp.mkdir(REMOTE_DIR)
            
        sftp.put(LOCAL_FILE_PATH, remote_file_path)
        sftp.chmod(remote_file_path, 0o755)
        sftp.close()
        print(">>> 文件上传成功并已设置可执行权限。")

        # 5. 启动新程序
        print(f"5. 正在启动新程序: {remote_file_path}")
        start_command = (
            f"MEDIASOUP_WORKER_BIN=/home/mediasoup/mediasoup-demo/server/node_modules/mediasoup/worker/out/Release/mediasoup-worker "
            f"nohup {remote_file_path} -config=/home/teck/media.config.json > {REMOTE_DIR}/media_app.log 2>&1 &"
        )
        ssh_client.exec_command(start_command)
        print(">>> 程序已在后台启动。")

        # 6. 检查程序是否在后台正常运行
        print("6. 正在检查程序是否在后台运行...")
        check_command = f"pgrep -f {executable_name}"
        stdin, stdout, stderr = ssh_client.exec_command(check_command)
        pid_list = stdout.read().decode().strip()
        if pid_list:
            print(f">>> 程序已在后台运行，PID: {pid_list}")
            print(">>>部署成功！")
        else:
            print("!!! 警告：未检测到程序在后台运行，请检查日志或手动排查。")

    except Exception as e:
        print(f"!!! 发生错误: {e}")
    finally:
        if ssh_client:
            ssh_client.close()
            print("SSH 连接已关闭。")

if __name__ == '__main__':
    main()